/* eslint-disable no-param-reassign */
import React from 'react';
import { Form, Input, ResponsiveGrid } from '@alifd/next';
import { t } from '@lingui/macro';
import dayjs from 'dayjs';
import _ from 'lodash';
import { observer } from 'mobx-react-lite';

const { Cell } = ResponsiveGrid;
const FormItem = Form.Item;

export const DATETIME_TEXT = (v) => (v ? dayjs(v).format(DATETIME_FORMAT) : '');
export const DATETIMES_TEXT = (v) => (v ? dayjs(v).format(DATETIMES_FORMAT) : '');
export const DATE_TEXT = (v) => (v ? dayjs(v).format(DATE_FORMAT) : '');
export const TIME_TEXT = (v) => (v ? dayjs(v).format(TIME_FORMAT) : '');
export const EMPTY_TEXT = (v) => (v || t`无`);

export const ENUMS = {
  currency: {
    RMB: t`人民币`,
    HKD: t`港币`,
    MOP: t`澳门币`,
  },
};

/**
 * 分转换元  保留两位小数
 * @param {*} num 金额
 * @param {*} count 保留几位小数
 * @returns string
 */
export function _amountConversion(num, count = 2) {
  const price = num ? Number(num) : 0;
  return (price / 100).toFixed(count);
}

/**
 * 返回字段标题
 * @param {string} path
 * @returns string
 */
export function getField(model, path = '') {
  const key = path.match(/\{(\w+)\}/)?.[1];
  if (key) path = path.replace(/\{(\w+)\}/, '{key}');
  const rtn = _.cloneDeep(_.get(model, path));
  if (!rtn) throw new Error(`Field definition not found for path: ${path}`);
  rtn.key = key;
  return rtn;
}

/**
 * @param {object} model  模型定义
 * @param {*} path        属性path
 * @param {*} props       column属性
 * @returns column定义
 */
export function column(model, path, props, subModel) {
  const field = getField(subModel || model, path);
  const { text: textFunc } = field;
  const ui = field['ui_table'] || {};
  // const ui = field['ui'] || {};
  // _.merge(ui, field['ui_table'] || {});

  if (!props.cell) {
    if (ui.renderer) {
      props.cell = !textFunc ? ui.renderer : (v, i, row) => ui.renderer(textFunc(v, row), i, row);
    } else if (textFunc) {
      props.cell = (v, i, row) => textFunc(v, row);
    }
  }
  return { title: field.label, dataIndex: path, ...props };
}

// 枚举转换为select所需的data
const trans = (r, v, k) => { if (v) { r.push({ label: v, value: k }); } };
export function toSelectDataSource(enumMap) {
  return [...(_.transform(enumMap, trans, []))];
}

export const titleCellProps = {
  style: { fontWeight: t`500`, fontSize: t`var(--font-size-subhead, 16px)`, margin: '10px 0' },
};

/**
 * 显示表单字段分组标题
 * @param {object} param0
 * @returns
 */
export function TitleGrid({ title, children, gridProps, ...props }) {
  return (
    <ResponsiveGrid gap={12} {...gridProps}>
      <Cell {...titleCellProps} colSpan={2} className="sub-title" {...props}>
        {title}
      </Cell>
      {children}
    </ResponsiveGrid>
  );
}

const FormField = observer(({ formData, path, field, def, mode, itemLayout, onCell, colon }) => {
  const value = _.get(formData, path);
  const { text: textFunc, key } = field;
  let { label } = field;
  if (key) label = label.replace(/\[(\w+)\]/, key);
  if (colon && (!label.endsWith(':') || !label.endsWith('：'))) label = `${label} : `;

  const { renderer } = def;
  const cellProps = {};
  const isPreview = mode === 'view';
  const exItemProps = { isPreview };
  const itemProps = typeof def.itemProps === 'function' ? def.itemProps({ ...exItemProps, mode, ...def, value, formData }) : def.itemProps;
  if (isPreview && itemProps?.required === true) {
    itemProps.required = false;
  }

  _.assign(exItemProps, itemProps);
  const { placeholder = t`请输入${label}` } = exItemProps;

  const cfg = { path, label, cellProps, itemProps: exItemProps, itemLayout: { style: { marginBottom: isPreview ? 0 : 10, width: '100%' }, ...itemLayout } };
  onCell?.(cfg); // 允许重写最终的属性

  const component = renderer ? renderer(value, formData, { isPreview, ...cfg })
    : <Input placeholder={placeholder} value={value === null || value === undefined ? undefined : value} renderPreview={(v) => (textFunc ? textFunc(v, formData) : EMPTY_TEXT(v))} />;

  return (
    <FormItem name={path} label={`${cfg.label}`} {...cfg.itemLayout} {...cfg.itemProps}>
      {component}
      {cfg.itemProps?.errorMsg &&
        <Form.Error name={path}>
          {(errors, state) => {
            if (state === 'loading') {
              return t`校验中...`;
            } else {
              return errors;
            }
          }}
        </Form.Error>}
    </FormItem>
  );
});

function renderCell({ model, path, props }) {
  if (path.endsWith('.')) path = '';
  if (!path) return <Cell />;

  const { overrideModel, mode = 'edit', ...leftProps } = props;
  const overrideFieldModel = _.get(overrideModel, path);
  const field = getField(model, path);
  _.merge(field, overrideFieldModel);
  const { ui } = field;
  const modeUi = field[`ui_${mode}`];
  const def = _.merge({}, ui, modeUi);
  const { span } = def;
  const cellProps = {};
  if (span) {
    _.assign(cellProps, { className: `grid-${span}`, colSpan: span });
  }

  return <Cell key={path} {...cellProps}><FormField path={path.replace(/\{|\}/g, '')} field={field} def={def} mode={mode} {...leftProps} /></Cell>;
}

/**
 * 显示一组表单字段
 * ```js
 * {
 *   fields: string[],    // 字段名称，可以使用.来指定嵌套对象属性，例如order.busOrder.shift
 *   columns: number,     // 列数，默认为4,最大为12,最小为1
 *   model: object,       // 字段定义数据模型的根对象，默认不指定，仅在使用子对象作为根模型时设置
 *   overrideModel: object, // 重载字段定义数据模型
 *   mode: string,        // 表单模式，默认为edit，可选view
 *   itemLayout: object,  // FormItem布局配置，默认为{}
 * }
 * ```
 *
 * @param {object} param0
 * @returns
 */
export function FieldsGrid({ fields, columns = 4, model, ...props }) {
  props.colon = columns === 1;
  return (
    <ResponsiveGrid gap={[0, 24]} columns={columns}>
      {fields.map((path) => {
        return renderCell({ model, path, props });
      })}
    </ResponsiveGrid>
  );
}
